package resources;


import java.util.ArrayList;

import recordsDatabase.Category;
import recordsDatabase.CategoryDetails;
import recordsDatabase.ListOfCategories;
import recordsDatabase.ListOfPersons;
import recordsDatabase.Person;
import recordsDatabase.Record;



//Populator thread
public class Populator{
	
	private String category;
	private Person currentPerson = null;
	private FileReaderWriter file = new FileReaderWriter();

	
	public Populator() {}
	
	
	
	public void loadData(String fileName){
		StringBuilder contents = new StringBuilder();
		// read file
		contents = file.ReadFile(fileName);
		// pass each line to the populator to process it!
		int endIndex = 0;
		int startIndex = 0;
		String line = "";
		while (endIndex != contents.length() - 1) {
			endIndex = contents.indexOf("\n", startIndex);
			line = contents.substring(startIndex, endIndex);
			processLine(line);
			startIndex = endIndex + 1;
		}
	}
	
	private void processLine(String line) {
		if (!line.isEmpty() & line.length() > 5) {
			// remove commas within parenthesis to avoid wrong interpretation
			line = removeCommasWithinParenthesis(line);
			if (isName(line)) {
				category = "Name";
				// step 1 | create a category if it does not exist and add it to the
				// list
				if (!ListOfCategories.getInstance().categoryExists(category)) {
					Category newCategory = new Category(category);
					ListOfCategories.getInstance().addEntry(newCategory);
				}
				// step 2 | check if a categoryDetails already exists with that
				// Name.
				if (!ListOfCategories.getInstance().getCategory(category)
						.entryExistsInList(line)) {
					CategoryDetails categoryDetails = new CategoryDetails(line);
					// step 4 | add that categoriesDetails to the category list
					ListOfCategories.getInstance().getCategory(category)
							.addEntry(categoryDetails);
					
				} 
				// step 5 | create a person and add his name as a record. Then
				// add him to the list
				currentPerson = new Person();
				Record r = new Record(category, ListOfCategories.getInstance()
						.getCategory(category).getCategoyDetails(line));
				currentPerson.addElement(r);
				ListOfPersons.getInstance().addPerson(currentPerson);
				//add that person inside the list of persons of that category details
				ListOfCategories.getInstance().getCategory(category).getCategoyDetails(line).addPerson(currentPerson);
			} else {
				if (isCategory(line)) {
					category = line.substring(0, line.indexOf(":"));
					// step 1 | create a category if it does exist and add it to
					// the list
					if (!ListOfCategories.getInstance()
							.categoryExists(category)) {
						Category newCategory = new Category(category);
						ListOfCategories.getInstance().addEntry(newCategory);
					}
					// step 2 | extract the data from the line
					ArrayList<String> list = new ArrayList<String>();
					list = extractData(line);
					// step 3 | create a list of categoryDetails objects if they
					// do not exist for that data inside that category
					ArrayList<CategoryDetails> cdList = new ArrayList<CategoryDetails>();
					for (String s : list) {
						if (!ListOfCategories.getInstance().getCategory(
								category).entryExistsInList(s)) {
							// step 4 | create a categoryDetails from that entry
							CategoryDetails categoryDetails = new CategoryDetails(s);
							// step 5 | add him to the categoryDetails list
							categoryDetails.addPerson(currentPerson);
							// step 6 | add that categoriesDetails to the
							// category list
							ListOfCategories.getInstance()
									.getCategory(category).addEntry(
											categoryDetails);
						} else {
							ListOfCategories.getInstance()
									.getCategory(category).getCategoyDetails(s)
									.addPerson(currentPerson);
						}
						cdList.add(ListOfCategories.getInstance()
								.getCategory(category).getCategoyDetails(s));
					}
					// step 7 | load the existing person and add this
					// category data as a record to his person object.
					Record r = new Record(category, cdList);
					currentPerson.addElement(r);
				}
			}
		}
	}

	private boolean isName(String line) {
		// check if the first four characters are upper case. If yes then it
		// must be a name.
	if (line.contains("Ref:"))	return true;
	else	return false;
	}

	private ArrayList<String> extractData(String line) {
		char separator = ',';
		if (line.contains("References:") || line.contains("Appointments Held:")
				|| line.contains("Father:") || line.contains("Mother:")
				|| line.contains("Place of Birth:")
				|| line.contains("Place of Death:")
				|| line.contains("Place of interment:"))
			separator = ';';

		ArrayList<String> professionsList = new ArrayList<String>();
		line = line.substring(line.indexOf(":") + 1, line.length() - 1);
		if (line.indexOf(separator) == -1) {
			professionsList.add(line.substring(0, line.length()));
			return professionsList;
		} else {
			String profession = "";
			int startIndex = 0;
			int endIndex = 0;
			while (endIndex != line.length() - 1) {
				endIndex = line.indexOf(separator, startIndex);
				if (endIndex == -1) {
					endIndex = line.length() - 1;
					profession = line.substring(startIndex, endIndex + 1);
				} else
					profession = line.substring(startIndex, endIndex);
				professionsList.add(profession);
				startIndex = endIndex + 1;
			}
			return professionsList;
		}

	}

	private boolean isCategory(String line) {
		char upperCase = line.charAt(0);

		if (line.indexOf(":") != -1 & Character.isUpperCase(upperCase)) {
			return true;
		} else
			return false;
	}

	private String removeCommasWithinParenthesis(String line) {
		StringBuilder newLine = new StringBuilder(line);
		int index = 0;
		boolean start = false;
		while (index != newLine.length() - 1) {
			if (newLine.charAt(index) == '(') {
				start = true;
			}
			if (start) {
				if (newLine.charAt(index) == ',') {
					newLine.deleteCharAt(index);
					newLine.insert(index, ' ');
				} else if (newLine.charAt(index) == ')') {
					start = false;
				}
			}
			index++;
		}
		return newLine.toString();
	}

	
	
}
